package com.biostime.qdingding.modules.qd.service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.biostime.qdingding.common.service.CrudService;
import com.biostime.qdingding.common.utils.DateUtils;
import com.biostime.qdingding.common.utils.StringUtils;
import com.biostime.qdingding.modules.qd.api.dto.MyCourseDto;
import com.biostime.qdingding.modules.qd.api.dto.MyCourseParamDto;
import com.biostime.qdingding.modules.qd.api.dto.PersonalCenterDto;
import com.biostime.qdingding.modules.qd.api.BasicApi;
import com.biostime.qdingding.modules.qd.api.dto.BalanceDto;
import com.biostime.qdingding.modules.qd.api.dto.ButtonDto;
import com.biostime.qdingding.modules.qd.api.dto.ContractDto;
import com.biostime.qdingding.modules.qd.api.dto.CourseCalendarParamDto;
import com.biostime.qdingding.modules.qd.api.dto.CourseDetailDto;
import com.biostime.qdingding.modules.qd.dao.ContractDao;
import com.biostime.qdingding.modules.qd.dao.CourseDao;
import com.biostime.qdingding.modules.qd.dao.CourseOrderDao;
import com.biostime.qdingding.modules.qd.entity.Center;
import com.biostime.qdingding.modules.qd.entity.Contract;
import com.biostime.qdingding.modules.qd.entity.Coupon;
import com.biostime.qdingding.modules.qd.entity.Course;
import com.biostime.qdingding.modules.qd.entity.CourseOrder;
import com.biostime.qdingding.modules.qd.entity.Courseprice;
import com.biostime.qdingding.modules.qd.entity.Member;
import com.biostime.qdingding.modules.qd.entity.MemberCoupon;
import com.biostime.qdingding.modules.qd.entity.Privilege;
import com.biostime.qdingding.modules.qd.entity.Student;
import com.biostime.qdingding.modules.qd.entity.Transrecord;
import com.biostime.qdingding.modules.qd.push.MsgTemplate;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.Abort;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.CancelOrder;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.CancelQuery;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.Leave;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.Order;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.Query;
import com.biostime.qdingding.modules.qd.push.PushMessage;
import com.biostime.qdingding.modules.qd.push.PushService;
import com.biostime.qdingding.modules.qd.service.BookConfirmService.BookResult;
import com.biostime.qdingding.modules.qd.utils.CalendarUtils;
import com.biostime.qdingding.modules.qd.utils.CalendarUtils.WeekInfo;
import com.biostime.qdingding.modules.sys.entity.User;
import com.biostime.qdingding.modules.sys.utils.UserUtils;

@Service
@Transactional(readOnly = true)
public class CourseOrderService extends CrudService<CourseOrderDao, CourseOrder> {
	
	private final static int FREE_ORDER_COUPON_ID = 1;

	@Autowired
	private CourseOrderDao courseOrderDao;

	@Autowired
	private CourseDao courseDao;
	
	@Autowired
	private PriceService priceService;
	
	@Autowired
	private BookConfirmService confirmService;
	
	@Autowired
	private StudentService studentService;
	
	@Autowired
	private CenterService centerService;
	
	@Autowired
	private MemberService memberService;
	
	@Autowired
	private CoursepriceService coursepriceService;
	
	@Autowired
	private MessageService messageService;	
	
	@Autowired
	private TransrecordService recordService;	
		
	@Autowired
	private PrivilegeService privilegeService;
	
	@Autowired
	private ContractService contractService;
	
	@Autowired
	private PrivrecordService privrecordService;
	
	@Autowired
	private CouponService couponService;
	
	@Autowired
	private ContractDao contractDao;
	
	@Autowired
	private TransrecordService transrecordService;
	
	@Autowired 
	private MemberCouponService memberCouponService;
		
	public static Logger logger=Logger.getLogger("api"); 

	/**
	 * 获取学员预约课程排名
	 * @param studentId
	 * @return
	 */
	public int getRank(Course course) {
		
		int number = course.getRank();
		
		if(number!=0){
			return number;
		}
		
		List<HashMap<String,String>> lists = dao.getRank(course);
		
		HashMap<String,String> student = null;
		HashMap<String,String> all = null;
		
		for(HashMap<String,String> map : lists){
			if(map.get("category").equals("all")){
				all = map;
			}
			if(map.get("category").equals("student")){
				student = map;
			}
		}
		
		if(student != null){
			number = StringUtils.toInteger(student.get("rank"));
		}else{
			number = StringUtils.toInteger(all.get("rank"));
		}
		
		return number;
	}
	
	@Override
	public List<CourseOrder> findList(CourseOrder entity) {
		dataScopeFilter(entity, "dsf", "id=a.center_id", "id=a.create_by");
		
		return super.findList(entity);
	}

	public CourseOrder getforcsId(CourseOrder courseOrder){
		return courseOrderDao.getforcsId(courseOrder);
	}

	/**
	 * 中止课程
	 * @return
	 */
	public String abortOrder(HttpServletRequest request) {
		String message = "";
		
		String userId = request.getParameter("userId");
		String type = request.getParameter("type");
		String studentId = request.getParameter("studentId");
		String courseId = request.getParameter("courseId");			
		CourseOrder courseOrder = apiGetByStuAndCourse(courseId, studentId, type);
		
		@SuppressWarnings("unused")
		int id = 0;
		
		if(courseOrder != null && !courseOrder.getState().equals("aborted")){
			try{
				id = apiChangeOrder((courseOrder.getId()), "aborted");
				
				//修改优惠券使用记录，标记为未使用
				if(courseOrder.getCouponId() == null){
					courseOrder.setCouponId(0); 
				}
				couponService.useCoupon(String.valueOf(courseOrder.getCouponId()) ,"0"); 
				
				Course course =courseDao.apiGetInOrOut(type, courseId);			
									
					//学员合同
					String contractId = null;
					String centerId = null;
					List<ContractDto> contractList = contractService.apiGetContract(studentId);
					if(contractList != null && !contractList.isEmpty()){
						contractId = String.valueOf(contractList.get(0).getId());
						centerId = String.valueOf(contractList.get(0).getCenterId());	
						
						//添加收支记录
						SimpleDateFormat df =null;
						request.setAttribute("contractId", contractId);	
						request.setAttribute("userId", userId);	
						request.setAttribute("studentId", studentId);	
						request.setAttribute("centerId", centerId);	
						request.setAttribute("orderId", courseOrder.getId()); 	
						request.setAttribute("type", type); 	
						df = new SimpleDateFormat("MM月dd日");
						String str = "["+df.format(course.getOndate())+" "+course.getClevel()+course.getSerial()+"]";
						request.setAttribute("str", str); 
						double money = recordService.apiInsertTrans(request,"abort");		
												
						//发送中止通知
						df = new SimpleDateFormat("MM月dd日");
						String msg = Abort.content;
						msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
						msg = msg.replace(MsgTemplate.section, course.getSection());
						msg = msg.replace(MsgTemplate.level, course.getClevel());
						msg = msg.replace(MsgTemplate.serial, course.getSerial());
						msg = msg.replace(MsgTemplate.theme, course.getTheme());
						msg = msg.replace(MsgTemplate.money, String.format("%.1f",money));
						
						String pushMsg = Abort.push;
						pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
						pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
						pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
						pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
						pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
						pushMsg = pushMsg.replace(MsgTemplate.money, String.format("%.1f",money));
						
						messageService.sendAndPush(Abort.category, String.valueOf(studentId), Abort.title, msg, String.valueOf(userId), pushMsg);
					
					}					
					
				}catch(Exception ex){
				message = "中止过程出现异常";
				ex.printStackTrace();
			}
		}else{
			message = "请确认是否预约该课程";
		}
		
		return message;
	}	

	public List<CourseOrder> findOrderStudents(CourseOrder courseOrder) {
		return dao.findOrderStudents(courseOrder);
	}
	
	public int getCouponCount(CourseOrder courseOrder){
		return dao.getCouponCount(courseOrder);
	}
	
	/**
	 * 用于保存临时约课合同
	 */
	@Transactional
	public void saveTempOrder(CourseOrder courseOrder){
		courseOrder.setOrderno("TS"+DateUtils.formatDate(new Date(), "yyyyMMddHHmmss"));
		courseOrder.setType(0);
		courseOrder.setCourseId(Integer.valueOf(courseOrder.getCourse().getId()));
		courseOrder.setStudentId(Integer.valueOf(courseOrder.getContract().getStudent().getId()));
		courseOrder.setNum(0);
		courseOrder.setPrice(courseOrder.getActualPayPrice());
		courseOrder.setFreeze(0.0);
		courseOrder.setPaid(1);
		courseOrder.setContractId(Integer.valueOf(courseOrder.getContract().getId()));
		courseOrder.setState("signed");
		courseOrder.setCenterId(Integer.valueOf(courseOrder.getContract().getCenter().getId()));
		courseOrder.setCouponId(0);
		courseOrder.setCreateBy(UserUtils.getUser());
		courseOrder.setCreateDate(new Date());
		courseOrder.setUpdateBy(UserUtils.getUser());
		courseOrder.setUpdateDate(new Date());
		dao.insert(courseOrder);
		
		
		Transrecord transrecord = new Transrecord();
		transrecord.setInout(1);
		transrecord.setType("3");
		transrecord.setMoney(courseOrder.getActualPayPrice());
		transrecord.setPayType("5");
		transrecord.setPayDate(new Date());
		transrecord.setDescription("临时约课");
		transrecord.setMemberId(Integer.valueOf(courseOrder.getContract().getMember().getId()));
		transrecord.setInvalid(0);
		transrecord.setStudentId(Integer.valueOf(courseOrder.getContract().getStudent().getId()));
		transrecord.setCourseorderId(Integer.valueOf(courseOrder.getId()));
		transrecord.setContractId(Integer.valueOf(courseOrder.getContract().getId()));
		transrecord.setCenterId(Integer.valueOf(courseOrder.getContract().getCenter().getId()));
		transrecord.setCreateBy(UserUtils.getUser());
		transrecord.setCreateDate(new Date());
		transrecord.setUpdateBy(UserUtils.getUser());
		transrecord.setUpdateDate(new Date());
		transrecordService.save(transrecord);
	}
	
	//免费预约时 创建合同 发放优惠券 约课
	@Transactional
	public String freeOrder(Contract contract ,String courseId){
		Member member = contract.getMember();
		member.setName(member.getNikename());
		member.setLoginFlag("0");
		member.setCreateBy(UserUtils.getUser());
		member.setCreateDate(new Date());
		member.setUpdateBy(UserUtils.getUser());
		member.setUpdateDate(new Date());
		member.setDelFlag("0");
		memberService.apiInsert(member);
		contract = contractService.getByMobileStatus(contract);
		Course course = courseDao.get(courseId);
		MemberCoupon memberCoupon = new MemberCoupon();
		memberCoupon.setCouponId(FREE_ORDER_COUPON_ID);
		memberCoupon.setMemberId(Integer.parseInt(contract.getMember().getId()));
		memberCoupon.setIsUsed(String.valueOf(1));
		CourseOrder courseOrder = new CourseOrder();
		courseOrder.setCourseId(Integer.valueOf(course.getId()));
		courseOrder.setStudentId(Integer.valueOf(contract.getStudent().getId()));
		String errMessage = "";
		memberCouponService.save(memberCoupon);
		try {
			HashMap<String, Object> map = apiOrderCourse(course, "order", contract.getMember().getId(), contract.getStudent().getId(),String.valueOf(course.getType() ), memberCoupon.getId());
			errMessage = (String) map.get("message");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return errMessage;
	}
	
	//已有免费合同情况下 发放优惠券并预约
	@Transactional
	public String freeOrderCoupon(Contract contract, String courseId) {
		contract = contractService.getByMobileStatus(contract);
		Course course = courseDao.get(courseId);
		MemberCoupon memberCoupon = new MemberCoupon();
		memberCoupon.setCouponId(FREE_ORDER_COUPON_ID);
		memberCoupon.setMemberId(Integer.parseInt(contract.getMember().getId()));
		memberCoupon.setIsUsed(String.valueOf(0));
		CourseOrder courseOrder = new CourseOrder();
		courseOrder.setCourseId(Integer.valueOf(course.getId()));
		courseOrder.setStudentId(Integer.valueOf(contract.getStudent().getId()));
		String message = "";
		memberCouponService.save(memberCoupon);
		try {
			HashMap<String, Object> map = apiOrderCourse(course, "order", contract.getMember().getId(), contract.getStudent().getId(),String.valueOf(course.getType() ), memberCoupon.getId());
			message = (String) map.get("message");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("message ==================================="+message);
		return message;
	}
	
	public String giftOrderCoupon(Contract contract, String courseId) {
		String couponId = contract.getCouponId();
		contract = contractService.getByMobileStatus(contract);
		Course course = courseDao.get(courseId);
		CourseOrder courseOrder = new CourseOrder();
		courseOrder.setCourseId(Integer.valueOf(course.getId()));
		courseOrder.setStudentId(Integer.valueOf(contract.getStudent().getId()));
		String errMessage = "";
		try {
			HashMap<String, Object> map = apiOrderCourse(course, "order", contract.getMember().getId(), contract.getStudent().getId(),String.valueOf(course.getType() ), couponId);
			errMessage = (String) map.get("message");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return errMessage;
	}
	
	/*
	 * ================================================================================
	 * 		华丽分割线
	 * ===============================================================================
	 * */
	private void injectExtraData(List<MyCourseDto> l,String studentId){
		for(MyCourseDto cod:l){
			String courseId=cod.getCourseId()+"";
			String type=cod.getType()+"";
			int courseBook = apiCourseBook(courseId, type);
			int courseQueue = apiCourseQueue(courseId, type);
			cod.setBookNum(courseBook);
			cod.setQueueNum(courseQueue);
			Course course=new Course();
			course.setId(cod.getCourseId()+"");
			course.setType(cod.getType());
			course.setPrice(cod.getPrice());
			course.setPriceType(cod.getPriceType());
			course.setCapacity(cod.getCapacity()); 
			HashMap<String,Object> map=new HashMap<String,Object>();
			try {
				map=priceService.getPriceMap(course, studentId);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			Object moneyAfter = null;
			if(map != null){
				moneyAfter=map.get("moneyAfter");
			}
			if(moneyAfter!=null)cod.setPrice(moneyAfter.toString());
		}
	}
	
	/**
	 * 课程分组
	 * 课程周日历专用
	 * @param needInjectData 是否需要注入价格相关信息
	 * @return 分组结果
	 */
	@SuppressWarnings("unchecked")
	public List<Map<String,Object>> apiParseWeekList(List<MyCourseDto> l,boolean needInjectData,String studentId){
		if(needInjectData)injectExtraData(l,studentId);
		List<Map<String,Object>> target=new ArrayList<Map<String,Object>>();
		
		for(MyCourseDto course:l){
			boolean dateExists=false;
			for(Map<String,Object> map : target){
				if(map.get("date").equals(course.getOnday())){
					boolean lmExists=false;
					List<Map<String,Object>> lm=(List<Map<String,Object>>)map.get("list");
					for(Map<String,Object> m:lm){
						if(m.get("sectionId").equals(course.getSectionId())){
							List<MyCourseDto> lc=(List<MyCourseDto>)m.get("list");
							lc.add(course);
							lmExists=true;
						}
					}
					if(!lmExists){
						Map<String,Object> newMap=new HashMap<String,Object>();
						List<MyCourseDto> lce=new ArrayList<MyCourseDto>();
						lce.add(course);
						newMap.put("sectionId",course.getSectionId());
						newMap.put("list", lce);
						lm.add(newMap);
					}
					dateExists=true;
				}
			}
			
			if(!dateExists){
				List<Object> list=new ArrayList<Object>();
				Map<String,Object> newMap=new HashMap<String,Object>();
				List<MyCourseDto> lce=new ArrayList<MyCourseDto>();
				lce.add(course);
				newMap.put("sectionId",course.getSectionId());
				newMap.put("list", lce);
				list.add(newMap);
				
				Map<String,Object> targetMap=new HashMap<String,Object>();
				targetMap.put("date", course.getOnday());
				targetMap.put("list", list);
				target.add(targetMap);
			}
			
		}
		return target;
	}
	/**
	 * 课程分组
	 * 课程月日历专用
	 * @param needInjectData 是否需要注入价格相关信息
	 * @return 分组结果
	 */
	public List<Map<String,Object>> apiParseMonthList(List<MyCourseDto> l,boolean needInjectData,String studentId){
		if(needInjectData)injectExtraData(l,studentId);
		List<Map<String,Object>> target=new ArrayList<Map<String,Object>>();
		for(MyCourseDto course:l){
			String month=course.getOnday().substring(0,7);
			boolean dateExists=false;
			for(Map<String,Object> map : target){
				if(map.get("month").equals(month)){
					boolean lmExists=false;
					@SuppressWarnings("unchecked")
					List<Map<String,Object>> lm=(List<Map<String,Object>>)map.get("list");
					for(Map<String,Object> m:lm){
						if(m.get("date").equals(course.getOnday())){
							@SuppressWarnings("unchecked")
							List<MyCourseDto> lc=(List<MyCourseDto>)m.get("list");
							lc.add(course);
							lmExists=true;
						}
					}
					if(!lmExists){
						Map<String,Object> newMap=new HashMap<String,Object>();
						List<MyCourseDto> lce=new ArrayList<MyCourseDto>();
						lce.add(course);
						newMap.put("date",course.getOnday());
						newMap.put("list", lce);
						lm.add(newMap);
					}
					dateExists=true;
				}
			}
			if(!dateExists){
				List<Object> list=new ArrayList<Object>();
				Map<String,Object> newMap=new HashMap<String,Object>();
				List<MyCourseDto> lce=new ArrayList<MyCourseDto>();
				lce.add(course);
				newMap.put("date",course.getOnday());
				newMap.put("list", lce);
				list.add(newMap);
				
				Map<String,Object> targetMap=new HashMap<String,Object>();
				targetMap.put("month", month);
				targetMap.put("list", list);
				target.add(targetMap);
			}
		}
		return target;
	}
	public List<Map<String,Object>> getMyCourseListByWeek(CourseCalendarParamDto cd){
		String[] week=cd.getWeekFrom().split("/");
		if(week==null||week.length<2)return null;
		WeekInfo wi=CalendarUtils.getWeek(Integer.parseInt(week[0]),Integer.parseInt(week[1]));
		cd.setWeekFrom(DateUtils.formatDate(wi.getCells().get(0).getDate(), "yyyy-MM-dd"));
		List<MyCourseDto> l=courseOrderDao.getMyCourseListByWeek(cd);
		for(MyCourseDto dto : l){
			int courseBook = apiCourseBook(String.valueOf(dto.getCourseId()), String.valueOf(dto.getType()));
			int courseQueue = apiCourseQueue(String.valueOf(dto.getCourseId()), String.valueOf(dto.getType()));	
			dto.setBookNum(courseBook);
			dto.setQueueNum(courseQueue); 
		}
		return apiParseWeekList(l,false,cd.getStudentId());
	}
	
	public List<Map<String,Object>> getMyCourseListByMonth(CourseCalendarParamDto cd){
		String[] month=cd.getMonthFrom().split("/");
		if(month==null||month.length<2)return null;
		cd.setMonthFrom(month[0]+"-"+month[1]+"-"+"01");
		List<MyCourseDto> l=courseOrderDao.getMyCourseListByMonth(cd);
		for(MyCourseDto dto : l){
			int courseBook = apiCourseBook(String.valueOf(dto.getCourseId()), String.valueOf(dto.getType()));
			int courseQueue = apiCourseQueue(String.valueOf(dto.getCourseId()), String.valueOf(dto.getType()));	
			dto.setBookNum(courseBook);
			dto.setQueueNum(courseQueue); 
		}		
		return apiParseMonthList(l,false,cd.getStudentId());
	}

	public List<Student> findByOrder() {
		return courseOrderDao.findByOrder();
	}
	
	@Transactional
	public String apiGetSeq(int type){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
		String dateStr=sdf.format(new Date());
		String reg=(type==1?"OC":"IC")+dateStr;
		String maxOrder=dao.apiGetMaxOrderNoByReg(reg);
		int maxOrderInt=0;
		if(maxOrder!=null && !maxOrder.equals(""))maxOrderInt=Integer.parseInt(maxOrder);
		return String.format("%s%05d", reg,maxOrderInt+1);
	}

	public int apiCourseBook(String courseId,String type) {
		return courseOrderDao.apiCourseBook(courseId,type);
	}

	public HashMap<String, Object> apiCourseOrder(String courseId, String studentId,String type) {
		return courseOrderDao.apiCourseOrder(courseId, studentId ,type);
	}
	
	public HashMap<String, Object> apiCourseQueuing(String courseId, String studentId,String type) {
		return courseOrderDao.apiCourseQueuing(courseId, studentId ,type);
	}	

	public int apiCourseQueue(String courseId,String type) {
		return courseOrderDao.apiCourseQueue(courseId ,type);
	}

	public int apiChangeOrder(String id, String state) {
		return courseOrderDao.apiChangeOrder(id, state);
	}

	public CourseOrder apiGetTopWaiting(String courseId) {
		return courseOrderDao.apiGetTopWaiting(courseId);
	}

	public CourseOrder apiGetByStuAndCourse(String courseId, String studentId,String type) {
		return courseOrderDao.apiGetByStuAndCourse(courseId, studentId ,type);
	}
	
	public List<CourseOrder> apiGetByStudent(String studentId,String state){
		return courseOrderDao.apiGetByStudent(studentId, state);
	}
	
	public List<CourseOrder> apiGetWentCourse(String studentId){	
		return courseOrderDao.apiGetWentCourse(studentId);
	}
	
	public List<MyCourseDto> apiGetWentOrNot(MyCourseParamDto cd){
		return courseOrderDao.apiGetWentOrNot(cd);
	}
	
	public List<MyCourseDto> apiGetWent(MyCourseParamDto cd){
		return courseOrderDao.apiGetWent(cd);
	}	
	
	public int apiCourseOrdAndQue(String courseId,String type){
		return courseOrderDao.apiCourseOrdAndQue(courseId ,type);
	}
	
	public List<CourseOrder> apiGetAllList(Member member){
		return dao.apiGetMyCourseOrder(member);
	}
	
	public HashMap<String,Object> apiGetOrderId(String courseId,String type,String studentId){
		return  dao.apiGetOrderId(courseId, type,studentId);
	}
	
	public List<CourseOrder> apiGetRecentCourder(String studentId){
		return dao.apiGetRecentCourder(studentId);
	}

	public List<CourseOrder> getCenterData(CourseOrder courseOrder){
		dataScopeFilter(courseOrder, "dsf", "id=a.center_id", "id=a.create_by");
		return dao.getCenterData(courseOrder);
	}
	
	public List<CourseOrder> getCenterDatas(CourseOrder courseOrder){
		dataScopeFilter(courseOrder, "dsf", "id=a.center_id", "id=a.create_by");
		return dao.getCenterDatas(courseOrder);
	}	
	
	/**
	 * 参数校验,对courseId,studentId,userId,type,centerId
	 * 作统一简单的非空校验
	 */
	public HashMap<String,Object> apiCheckParameter(String courseId, String studentId, String userId, String type,String centerId) {
		boolean flag = false;
		Student student = null;
		PersonalCenterDto member = null;
		Center center = null;
		String errMessage = null;
		
		//简单非空校验
		if ((courseId != null && !courseId.equals("")) && studentId != null && !studentId.equals("")) {
			if ((userId != null && !userId.equals("")) && (type != null && !type.equals(""))) {
				if(centerId != null && !centerId.equals("")){
					flag = true;
				}
			}
		}
		
		//判断courseId是否为空
		if(courseId == null || courseId.equals("")){
			flag = false;
			errMessage = "课程id不能为空";
		}
		
		//判断学生是否存在
		if(studentId == null || studentId.equals("")){
			flag = false;
			errMessage = "学生id不能为空";
		}else{
			if(!studentId.equals("NOT-NULL") && !studentId.equals(String.valueOf(BasicApi.defaultStudentId))){ 
				student = studentService.apiGetStudentById(studentId);
				if(student == null ){
					flag = false;
					errMessage = "不存在该学生";
				}					
			}
		}
		
		//判断用户是否存在
		if(userId == null || userId.equals("")){
			flag = false;
			errMessage = "用户id不能为空";
		}else{
			if(!userId.equals("NOT-NULL") && !userId.equals(String.valueOf(BasicApi.defaultUserId))){
				member = memberService.apiGet(userId); 
				if(member == null){
					flag = false;
					errMessage = "不存在该用户";
				}					
			}
		}
		
		//判断课程类型是否为空
		if(type == null || type.equals("")){
			flag = false;
			errMessage = "课程类型不能为空";
		}
		
		//判断中心是否存在
		if(centerId == null || centerId.equals("")){
			flag = false;
			errMessage = "中心id不能为空";
		}else{
			if(!centerId.equals("NOT-NULL")){
				center = centerService.apiGetById(centerId);
				if(center == null){
					flag = false;
					errMessage = "不存在该中心";
				}				
			}
		}		
		
		HashMap<String,Object> checkMap = new HashMap<String,Object>();
		checkMap.put("flag", flag);
		checkMap.put("errMessage",errMessage);
		return checkMap;
	}
	
	/**
	 * 推送消息
	 * @param hashMap
	 */
	public void sendMessage (HashMap<String,Object> hashMap){		
		if(hashMap != null){
			PushMessage msg = new PushMessage();
			
			//类型
			String category = (String) hashMap.get("category");
			
			//内容
			String content = (String) hashMap.get("content");
			
			//标题
			String title = (String) hashMap.get("title");
			
			//日期
			Date date = (Date) hashMap.get("date");
			
			//用户id
			String userId = (String) hashMap.get("userId");
			
			//消息id
			String messageId = (String) hashMap.get("id");
			
			msg.setId(messageId);
			msg.setCategory(category);
			msg.setTitle(title);
			msg.setContent(content);
			msg.setCleared(true);
			msg.setRedirect("http://www.baidu.com");
			msg.setTime(date);	
			
			PushService.pushMessageToSingle(userId, msg);				
		}
	}

	//并发代码锁
	private static Object orderLock = new Object();
	
	/**
	 * 预约课程,加入等位
	 * 包括室内，和户外课程
	 * @Param orderType:queue(加入等位),order(预约)
	 * 
	 */
	@Transactional
	public HashMap<String, Object> apiOrderCourse(Course course, String orderType, String userId,String studentId,String type,String couponId) 
			throws Exception{
		int id = 0;
		String courseId = course.getId();
		
		HashMap<String, Object> map = new HashMap<String, Object>();
		
		synchronized (orderLock) {

			//当前预约人数
			int num = courseOrderDao.apiCourseBook(courseId,type);

			//课程容量
			int capacity = courseDao.get(courseId).getCapacity();
					
			//判断该预约是否满足预约条件		
			BookResult result = confirmService.confirm(userId, studentId, courseId, 0);
			int errCode = result.getErrCode();
			String message = result.getMsg();
			
			map.put("message", message);
			map.put("state", "false");
					
			//判断order是否存在
			if (courseOrderDao.apiGetByStuAndCourse(courseId, studentId,type) != null) {					
				String state = courseOrderDao.apiGetByStuAndCourse(courseId, studentId,type).getState();		
				if (!state.equals("canceled")) {
					map.put("message", "不好意思，您已预约或已参加排队");
				} 						
			} else {		
				
				CourseOrder courseOrder = new CourseOrder();		
				Coupon coupon = new Coupon();
				coupon.setType("非空"); 
				
				//再次校验优惠券是否可用
				if(couponId != null && !couponId.equals("")){
						coupon = couponService.selectByMemberCouponId(couponId);
				}			
				
				//判断能否到预约时间,为使用优惠券专门使用
				boolean orderOrNot = confirmService.notOrderTime(courseId,Integer.parseInt(type));
				
				//如果已过预约时间，则提示
				if(!orderOrNot){
					map.put("message", "该课程已过预约时间");
				}
				
				if(errCode == 0 || (coupon.getType().equals("free")  && orderOrNot) || (coupon.getType().equals("gift")  && orderOrNot)){	
						
					
					
					Student student=new Student();
					student.setId(studentId);
					double myBalance = 0d;
					
					//我的账户余额
					if(recordService.getBalance(student) != null){
						BalanceDto balance = recordService.getBalance(student);
						myBalance = priceService.changeMoney(balance.getSumPay() - balance.getSumCost() - balance.getSumFreeze());			
					}

					//需要动态判断，是闲时，忙时，闲时为分段价格，忙时为统一价格		
					double discount = 10d;
					courseOrder.setPrice(0d);
			
					HashMap<String,Object> priceMap = priceService.getPriceMap(course,studentId);
					double moneyBefore = (double) priceMap.get("moneyBefore");
					discount = (double) priceMap.get("discount") * 0.1;
									
					if(course.getPriceType() == 0){

						//如果账户余额小于优惠前价格大于预估价格，则冻结金额为账户余额
						if(myBalance<moneyBefore*discount){
							courseOrder.setFreeze(myBalance); 
						}else{
							courseOrder.setFreeze(moneyBefore*discount); 	
						}

					}else if(course.getPriceType() == 1){

						double initPrice = 0;
						String centerId = String.valueOf(BasicApi.defaultCenterId);
						Center center = centerService.getCenterByStudent(student);
						if(center != null){
							centerId = center.getId();
						}
						List<Courseprice> coursePrice = coursepriceService.apiGetPrice(0, centerId);
						if(!coursePrice.isEmpty()){
							initPrice = coursepriceService.apiGetPrice(0, centerId).get(0).getPrice();
						}		
						initPrice=priceService.changeMoney(initPrice);

						//如果账户余额小于优惠前价格大于预估价格，则冻结金额为账户余额
						if(myBalance<initPrice*discount){
							courseOrder.setFreeze(myBalance); 
						}else{
							courseOrder.setFreeze(initPrice*discount); 	
						}	
						
					}
					
					//若优惠券类型是免费体验课，还有赠送券，则冻结金额为0
					if(couponId != null && !couponId.equals("")){
							if((coupon.getType().equals("free") || coupon.getType().equals("gift")) && 
									(coupon.getUseRange().contains(String.valueOf(course.getType())))){
								courseOrder.setFreeze(0d); 	
								
								//免费体验
								if(coupon.getType().equals("free")){
									map.put("message","使用免费体验券预约");
								}
								
								//赠课券
								else if (coupon.getType().equals("gift")){
									map.put("message","使用赠课券预约");
								}
							}
					}		
					
					courseOrder.setActualPayPrice(0d);
					courseOrder.setCourseId(Integer.parseInt(courseId));
					courseOrder.setStudentId(Integer.parseInt(studentId));
					courseOrder.setPaid(0);
					courseOrder.setNum(0); 
					courseOrder.setCenterId(course.getCenterId()); 
					courseOrder.setRemarks(course.getRemarks());
					
					//合同编号
					Contract contract = contractDao.getByStudentId(Integer.parseInt(studentId));
					courseOrder.setContractId(Integer.parseInt(contract.getId()));
					
					//优惠券编号
					if(couponId != null){
						courseOrder.setCouponId(Integer.parseInt(couponId)); 
					}else{
						courseOrder.setCouponId(0); 
					}
					
					//产生订单编号
					String orderNo = apiGetSeq(Integer.parseInt(type)); 
					courseOrder.setOrderno(orderNo); 		
					courseOrder.setCreateBy(new User("0"));
					courseOrder.setCreateDate(new Date());
					courseOrder.setUpdateBy(new User("0"));
					courseOrder.setUpdateDate(new Date());
					courseOrder.setDelFlag("0");
					courseOrder.setType(Integer.parseInt(type));	
					
					HashMap<String,Object> hashMap = new HashMap<String,Object>();
					hashMap.put("category", "ordered");
					hashMap.put("userId", userId);

					//预约操作
					if(orderType.equals("order")){
						if (num < capacity) {	
							
							//新增订单					
							courseOrder.setState("ordered");					
							id = courseOrderDao.apiOrderCourse(courseOrder);
							map.put("state", "true");
							
							//修改优惠券记录表，标记为已用
							couponService.useCoupon(String.valueOf(courseOrder.getCouponId()),"1"); 
							
							//发送预约通知
							SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
							String msg = Order.content;
							msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
							msg = msg.replace(MsgTemplate.section, course.getSection());
							msg = msg.replace(MsgTemplate.level, course.getClevel());
							msg = msg.replace(MsgTemplate.serial, course.getSerial());
							msg = msg.replace(MsgTemplate.theme, course.getTheme());
							
							String pushMsg = Order.push;
							pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
							pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
							pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
							pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
							pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
							
							messageService.sendAndPush(Order.category, String.valueOf(studentId), Order.title, msg, String.valueOf(userId), pushMsg);			
																						
						} else {
							map.put("message", "不好意思，由于课程容量已满，预约失败,是否加入排队？");
						}									
					}
							
					//等位操作
					else if(orderType.equals("queue")){
						if (num >= capacity) {	

							//新增订单					
							courseOrder.setState("queuing");					
							id = courseOrderDao.apiOrderCourse(courseOrder);
							map.put("state", "true");
							
							//发送等位通知
							SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
							String msg = Query.content;
							msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
							msg = msg.replace(MsgTemplate.section, course.getSection());
							msg = msg.replace(MsgTemplate.level, course.getClevel());
							msg = msg.replace(MsgTemplate.serial, course.getSerial());
							msg = msg.replace(MsgTemplate.theme, course.getTheme());
							
							//课程排位人数
							int courseQueue = courseOrderDao.apiCourseQueue(course.getId(), String.valueOf(course.getType()));
							msg = msg.replace(MsgTemplate.number, String.valueOf(courseQueue));
																			
							String pushMsg = Query.push;
							pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
							pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
							pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
							pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
							pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());

							messageService.sendAndPush(Query.category, String.valueOf(studentId), Query.title, msg, String.valueOf(userId), pushMsg);							
															
						} else {
							map.put("message", "您好，由于前面有人走了，您可以直接预约，是否预约？");
						}						
					}
					
				}
			}
		}

		map.put("id", id);
		map.put("courseId",course.getId());
		map.put("courseName", course.getSerial());
		map.put("date", course.getOndate());
			
		//日志打印
		String stateMessage = null;
		String orderMessage= null;
		if(map.get("state").equals("true")){ 
			orderMessage = "成功";
		}else{
			orderMessage = "失败";
		}
		if(orderType.equals("order")){
			stateMessage = "预约状况";
		}
		else if(orderType.equals("queue")){
			stateMessage = "等位状况";
		}
		CourseOrderService.logger.info("课程id:"+course.getId()+",课程类型:"+course.getType()
		+",课程名称:"+course.getSerial()+"," +stateMessage+ ":"+orderMessage+",提示信息："+map.get("message"));	 	
		
		return map;
	}	
	
	/**
	 * 请假操作
	 * @return
	 */
	public HashMap<String,Object> leaveCourse(HttpServletRequest request , String fromType){
		
		String userId = request.getParameter("userId");
		String type = request.getParameter("type");
		String studentId = request.getParameter("studentId");
		String courseId = request.getParameter("courseId");			
		CourseOrder courseOrder = apiGetByStuAndCourse(courseId, studentId, type);
		String message = null;
		int errCode = 1;
		
		if(courseOrder != null && !courseOrder.getState().equals("leaved")){
			
			boolean timeFlag = false;
			boolean isCharge = false;
			String errMessage = "请假失败";
			HashMap<String,Object> timeMap = confirmService.notLeaveTime(courseOrder,fromType);
			if(timeMap != null && !timeMap.isEmpty()){
				timeFlag = (boolean) timeMap.get("flag");
				isCharge = (boolean) timeMap.get("ifCharge");
				errMessage = (String) timeMap.get("errMessage");
			}	
						
			/**修改需求,待测试**/
			//判断是否到请假时间
			if(timeFlag){
				
				//修改订单为请假状态
				apiChangeOrder((courseOrder.getId()), "leaved");
				Course course =courseDao.apiGetInOrOut(type, courseId);		
				
				//获取个人请假信息
				HashMap<String,Object> leaveMap = personalPrivilege(studentId,"leave");
				int leaveTime = 0;
				int remainCount = 0;
				if(leaveMap != null){
					leaveTime = (int) leaveMap.get("leaveTime");
					remainCount = (int) leaveMap.get("remainCount");
				}				
				
				//发送请假通知
				SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
				String msg = Leave.Content;
				msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
				msg = msg.replace(MsgTemplate.section, course.getSection());
				msg = msg.replace(MsgTemplate.level, course.getClevel());
				msg = msg.replace(MsgTemplate.serial, course.getSerial());
				msg = msg.replace(MsgTemplate.theme, course.getTheme());
				msg = msg.replace(MsgTemplate.count, String.valueOf(leaveTime)); 
				
				String pushMsg = Leave.push;
				pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
				pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
				pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
				pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
				pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());					
				messageService.sendAndPush(Leave.category, String.valueOf(studentId), Leave.title, msg, String.valueOf(userId), pushMsg);					
				
				//判断是否到扣费时间
				if(isCharge){
						
					//判断能否使用请假特权
					if( (boolean) leaveMap.get("flag") ){
						
						//学员合同
						String contractId = null;
						String centerId = null;
						List<ContractDto> contractList = contractService.apiGetContract(studentId);
						if(contractList != null && !contractList.isEmpty()){
							contractId = String.valueOf(contractList.get(0).getId());
							centerId = String.valueOf(contractList.get(0).getCenterId());	
							
							//添加收支记录
							request.setAttribute("contractId", contractId);	
							request.setAttribute("userId", userId);	
							request.setAttribute("studentId", studentId);	
							request.setAttribute("centerId", centerId);	
							request.setAttribute("orderId", courseOrder.getId()); 	
							request.setAttribute("type", type); 
							df = new SimpleDateFormat("MM月dd日");
							String str = "["+df.format(course.getOndate())+" "+course.getClevel()+course.getSerial()+"]";
							request.setAttribute("str", str); 
							double money = recordService.apiInsertTrans(request,"leave");		
							
							//使用请假特权
							usePrivilege(studentId,"leave");
							
							//添加特权使用记录
							Privilege p = privilegeService.apiGetPrivilege("leave", contractId);	
							if(p != null){
								privrecordService.apiInsert(centerId, contractId, p.getId(), courseOrder.getId());		 				
							}
							
							//修改优惠券使用记录，标记为未使用
							if(courseOrder.getCouponId() == null){
								courseOrder.setCouponId(0); 
							}
							couponService.useCoupon(String.valueOf(courseOrder.getCouponId()) ,"0"); 
							
							//发送特权请假通知
							msg = Leave.privilegeContent;
							msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
							msg = msg.replace(MsgTemplate.section, course.getSection());
							msg = msg.replace(MsgTemplate.level, course.getClevel());
							msg = msg.replace(MsgTemplate.serial, course.getSerial());
							msg = msg.replace(MsgTemplate.theme, course.getTheme());
							msg = msg.replace(MsgTemplate.money, String.valueOf(money)); 
							msg = msg.replace(MsgTemplate.remainCount, String.valueOf(remainCount)); 
							msg = msg.replace(MsgTemplate.count, String.valueOf(leaveTime)); 
							
							pushMsg = Leave.privilegePush;
							pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
							pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
							pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
							pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
							pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
							pushMsg = pushMsg.replace(MsgTemplate.money, String.valueOf(money));						
							messageService.sendAndPush(Leave.category, String.valueOf(studentId), Leave.title, msg, String.valueOf(userId), pushMsg);							
							
							message = "请假成功,您已成功使用请假返款特权，上课费用已返款，请注意查收！";
							errCode = 0;
						}					
						
					}		
				}
				
				/**修改需求,待测试**/
				//如果未到扣费时间，则将正在排位的补上
				else{					
					cancelOrLeaveAfter(courseOrder,course);
				}	
		
				message = "请假成功";
				errCode = 0;
			}
			else{
				message = errMessage;
			}
		}else{
			message = "请假失败,您已请假";
		}
		
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("errCode",errCode);
		map.put("message", message);
		
		
		return map;
	}
	
	/**
	 * 使用请假特权,中止特权
	 * 请假（leave）,中止（abort）
	 */
	public HashMap<String,Object> usePrivilege(String studentId, String type){
				
		Privilege p1 = null;
		String contractId  = null;
		boolean flag = false;
		
		//学员合同
		List<ContractDto> contractList = contractService.apiGetContract(studentId);
		if(contractList != null && !contractList.isEmpty()){
			contractId = String.valueOf(contractList.get(0).getId());
			p1 = privilegeService.apiGetPrivilege(type, contractId);		
		}
		
		int total = 0;//总请假资格
		int leavePrivilege = 0;	//使用次数	
		int remainCount = 0;//剩余次数
		int leaveTime = 0;//请假次数
		int privilegeId = 0;//特权idd
		
		if(p1 != null){
			leavePrivilege = p1.getUsed();
			total = p1.getTotal();
			privilegeId = Integer.parseInt(p1.getId());
		}
		
		//如果请假资格不超过总次数
		if(leavePrivilege < total){
			
			//已使用次数
			leavePrivilege = leavePrivilege + 1;
			
			//剩余次数
			remainCount = total - leavePrivilege;
			
			//修改请假资格次数
			privilegeService.apiUpdatePrivilege(String.valueOf(privilegeId), leavePrivilege);	
			
			//请假标记
			flag = true;
		}
		
		//已请假次数
		leaveTime = privrecordService.apiGetLeaveCount(studentId);
		
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("useCount", leavePrivilege);
		map.put("remainCount", remainCount);
		map.put("leaveTime", leaveTime);
		map.put("flag", flag);
		
		return map;
	}	
	
	/**
	 * 获取个人请假信息
	 * 待完善(和使用请假特权方法一样)
	 * @author chenweicheng
	 * @version 2016-03-23
	 */
	public HashMap<String,Object> personalPrivilege(String studentId, String type){
		
		Privilege p1 = null;
		String contractId  = null;
		boolean flag = false;
		
		//学员合同
		List<ContractDto> contractList = contractService.apiGetContract(studentId);
		if(contractList != null && !contractList.isEmpty()){
			contractId = String.valueOf(contractList.get(0).getId());
			p1 = privilegeService.apiGetPrivilege(type, contractId);		
		}
		
		int total = 0;//总请假资格
		int leavePrivilege = 0;	//使用次数	
		int remainCount = 0;//剩余次数
		int leaveTime = 0;//请假次数
		
		if(p1 != null){
			leavePrivilege = p1.getUsed();
			total = p1.getTotal();
		}
		
		//如果请假资格不超过总次数
		if(leavePrivilege < total){
					
			//请假标记
			flag = true;
		}
		
		//已请假次数
		leaveTime = privrecordService.apiGetLeaveCount(studentId);
		
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("useCount", leavePrivilege);
		map.put("remainCount", remainCount);
		map.put("leaveTime", leaveTime);
		map.put("flag", flag);
		
		return map;
	}		
	
		
	/**
	 * 取消预约，等位操作
	 * @return
	 */	
	public HashMap<String,Object> cancelOrder(HttpServletRequest request){
		String userId = request.getParameter("userId");
		String type = request.getParameter("type");
		String studentId = request.getParameter("studentId");
		String courseId = request.getParameter("courseId");	
		int errCode = 1;
		String errMessage = null;	
		CourseOrder courseOrder = apiGetByStuAndCourse(courseId, studentId, type);
				
		if (courseOrder != null) {
			String orderId1 = courseOrder.getId();
			String state = courseOrder.getState();
			int paid = courseOrder.getPaid();
			
			if ((state.equals("ordered") || state.equals("queuing")) && paid == 0) {
				
				//判断是否过了取消课程时间
				if(confirmService.notCancelTime(courseId, Integer.parseInt(type))  || state.equals("queuing")){
					
					//修改订单状态为取消
					apiChangeOrder(orderId1, "canceled");
									
					//修改优惠券使用记录，标记为未使用
					if(courseOrder.getCouponId() == null){
						courseOrder.setCouponId(0); 
					}
					couponService.useCoupon(String.valueOf(courseOrder.getCouponId()) ,"0"); 
					errCode = 0;
					Course course = courseDao.apiGetInOrOut(type, courseId);				
				
					switch(state){	
					
						//取消预约
						case "ordered":
							
							//发送取消等位通知
							SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
							String msg = CancelOrder.content;
							msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
							msg = msg.replace(MsgTemplate.section, course.getSection());
							msg = msg.replace(MsgTemplate.level, course.getClevel());
							msg = msg.replace(MsgTemplate.serial, course.getSerial());
							msg = msg.replace(MsgTemplate.theme, course.getTheme());
							
							String pushMsg = CancelOrder.push;
							pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
							pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
							pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
							pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
							pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());						
							messageService.sendAndPush(CancelOrder.category, String.valueOf(studentId), CancelOrder.title, msg, String.valueOf(userId), pushMsg);								
							errMessage = "取消预约成功";
							
							break;	
							
						//取消等位
						case "queuing":
							
							//发送取消等位通知
							df = new SimpleDateFormat("MM月dd日");
							msg = CancelQuery.content;
							msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
							msg = msg.replace(MsgTemplate.section, course.getSection());
							msg = msg.replace(MsgTemplate.level, course.getClevel());
							msg = msg.replace(MsgTemplate.serial, course.getSerial());
							msg = msg.replace(MsgTemplate.theme, course.getTheme());
							
							pushMsg = CancelQuery.push;
							pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
							pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
							pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
							pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
							pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
							
							messageService.sendAndPush(CancelQuery.category, String.valueOf(studentId), CancelQuery.title, msg, String.valueOf(userId), pushMsg);								
							
							errMessage = "取消等位成功";
							
							break;
					}
					
					//修改该课程排队中最前的人的状态
					cancelOrLeaveAfter(courseOrder,course);
					
				}else{
					if(state.equals("ordered")){
//						errMessage = "取消预约失败,已过取消时间";
						errMessage = "请联系中心请假";
					}else{
						errMessage = "取消等位失败,已过取消时间";
					}					
				}
			
			}else{
				if(state.equals("ordered")){
					errMessage = "取消预约失败,已扣费的课程不能取消";
				}else{
					errMessage = "取消等位失败,已扣费的课程不能取消";
				}		
			}
		}
		
		HashMap<String,Object>  map = new HashMap<String,Object>();
		map.put("errCode", errCode);
		map.put("errMessage", errMessage);
		
		return map;
	}

	/**
	 * 是否显示按钮,且显示什么类型按钮
	 * @version 2016-03-07
	 * @return
	 */
	public  ButtonDto ifShowButton(CourseDetailDto courseDetail,String studentId){
		
		//初始化按钮，默认不显示
		ButtonDto button = new ButtonDto();
		button.setIsShow(false); 
		String state = courseDetail.getState();
		String courseId = String.valueOf(courseDetail.getId());
		String type = courseDetail.getType();
		CourseOrder courseOrder = apiGetByStuAndCourse(courseId, studentId, type);
		
		if(courseDetail != null){
			
			//判断学生是否与该课程产生关系
			if(state == null || state.equals("canceled")){ 
				
				//判断是否到预约，等位时间
				if(confirmService.notOrderTime( courseId, Integer.parseInt(courseId))){
					
					//判断是预约，还是等位
					if(courseDetail.getCapacity() > courseDetail.getCourseBook()){
						button.setName("预约");
						button.setType("ordered"); 
						button.setIsShow(true); 
					}else{ 
						button.setName("加入等位");
						button.setType("queuing"); 
						button.setIsShow(true); 						
					}
					
				}
			}else{
				
				//根据状态判断显示什么类型按钮
				boolean flag = false;
				HashMap<String,Object>  map = confirmService.notLeaveTime(courseOrder,"app");
				if(map != null && !map.isEmpty()){
					flag = (boolean) map.get("flag");
				}
				switch(state){
					case "ordered":
						if(confirmService.notCancelTime(courseId, Integer.parseInt(type))){
							button.setName("取消预约");
							button.setType("cancelOrdered"); 
							button.setIsShow(true); 
						}
						else if(flag){
							button.setName("请假");
							button.setType("leaved"); 
							button.setIsShow(true); 
						}						
						break;
					case "queuing":
						button.setName("取消等位");
						button.setType("cancelQueuing"); 
						button.setIsShow(true); 
						break;	
					default :
						button.setName(null);
						button.setType(null);
						break;	
				}
							
			}
		}
		
		return button;
	}	
	
	/**
	 * 当预约的人请假或者取消课程
	 * 将该课程排位最靠前的人的状态置为已预约
	 * @version 2016-03-11
	 */
	public void cancelOrLeaveAfter(CourseOrder  courseOrder,Course course){
		
		String courseId = course.getId();
		String state = courseOrder.getState();		
		
		if (apiGetTopWaiting(courseId) != null && state.equals("ordered")) {	
						
			//获取正在排位的排名最前一个会员的id
			CourseOrder order = apiGetTopWaiting(courseId);						
			String orderId2 = order.getId();
			String studentId2 = String.valueOf(order.getStudentId());
			String userId2 = "0";
			List<String> memberIds = memberService.apiGetParentId(studentId2);
			if(memberIds != null && !memberIds.isEmpty()){
				userId2 = memberIds.get(0);
			}
			
			if(orderId2 != null){	
				
				//修改该会员的状态为预约
				apiChangeOrder(orderId2, "ordered");	
				
				//发送预约通知
				SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
				String msg = Order.content;
				msg = msg.replace(MsgTemplate.date, df.format(course.getOndate()));
				msg = msg.replace(MsgTemplate.section, course.getSection());
				msg = msg.replace(MsgTemplate.level, course.getClevel());
				msg = msg.replace(MsgTemplate.serial, course.getSerial());
				msg = msg.replace(MsgTemplate.theme, course.getTheme());
				
				String pushMsg = Order.push;
				pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
				pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
				pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
				pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
				pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());				
				messageService.sendAndPush(Order.category, String.valueOf(studentId2), Order.title, msg, String.valueOf(userId2), pushMsg);		
																
			}
		}			
	}

}
